"""
对话记忆管理
管理对话历史和上下文
"""
from typing import List, Dict, Optional
from datetime import datetime
from loguru import logger

from app.db.redis_client import redis_manager
from app.config import settings


class ConversationMemory:
    """对话记忆管理器"""
    
    def __init__(self):
        """初始化记忆管理器"""
        self.redis = redis_manager
        self.max_history = settings.MAX_CONVERSATION_HISTORY
        self.ttl = settings.CONVERSATION_MEMORY_TTL
        
    async def save_message(
        self,
        user_id: str,
        role: str,
        content: str,
        metadata: Optional[Dict] = None
    ) -> bool:
        """
        保存消息到对话历史
        
        Args:
            user_id: 用户ID
            role: 角色（user/assistant/system）
            content: 消息内容
            metadata: 额外元数据
            
        Returns:
            是否成功
        """
        try:
            message = {
                "role": role,
                "content": content,
                "timestamp": datetime.now().isoformat(),
            }
            
            if metadata:
                message["metadata"] = metadata
            
            # 保存到Redis
            success = await self.redis.save_conversation_history(
                user_id=user_id,
                message=message,
                max_history=self.max_history
            )
            
            if success:
                logger.debug(f"消息已保存 | 用户: {user_id} | 角色: {role}")
            
            return success
            
        except Exception as e:
            logger.error(f"保存消息失败: {e}")
            return False
    
    async def get_history(
        self,
        user_id: str,
        limit: Optional[int] = None
    ) -> List[Dict]:
        """
        获取对话历史
        
        Args:
            user_id: 用户ID
            limit: 限制返回数量
            
        Returns:
            对话历史列表
        """
        try:
            limit = limit or self.max_history
            
            history = await self.redis.get_conversation_history(
                user_id=user_id,
                limit=limit
            )
            
            logger.debug(f"获取对话历史 | 用户: {user_id} | 数量: {len(history)}")
            
            return history
            
        except Exception as e:
            logger.error(f"获取对话历史失败: {e}")
            return []
    
    async def clear_history(self, user_id: str) -> bool:
        """
        清除对话历史
        
        Args:
            user_id: 用户ID
            
        Returns:
            是否成功
        """
        try:
            success = await self.redis.clear_conversation_history(user_id)
            
            if success:
                logger.info(f"对话历史已清除 | 用户: {user_id}")
            
            return success
            
        except Exception as e:
            logger.error(f"清除对话历史失败: {e}")
            return False
    
    def format_history_for_llm(
        self,
        history: List[Dict],
        max_tokens: int = 3000
    ) -> List[Dict[str, str]]:
        """
        格式化对话历史为LLM可用的格式
        
        Args:
            history: 对话历史
            max_tokens: 最大token数（近似）
            
        Returns:
            格式化的消息列表
        """
        messages = []
        total_chars = 0
        max_chars = max_tokens * 3  # 粗略估算：1 token ≈ 3字符
        
        # 从最新的消息开始处理
        for msg in reversed(history):
            role = msg.get("role", "user")
            content = msg.get("content", "")
            
            # 估算字符数
            msg_chars = len(content)
            if total_chars + msg_chars > max_chars:
                break
            
            messages.insert(0, {"role": role, "content": content})
            total_chars += msg_chars
        
        return messages
    
    async def summarize_conversation(
        self,
        user_id: str,
        llm_client=None
    ) -> Optional[str]:
        """
        总结对话内容（用于长对话）
        
        Args:
            user_id: 用户ID
            llm_client: LLM客户端实例
            
        Returns:
            对话摘要
        """
        try:
            # 获取完整历史
            history = await self.get_history(user_id)
            
            if not history:
                return None
            
            # 格式化对话
            conversation_text = "\n".join([
                f"{msg['role']}: {msg['content']}"
                for msg in history
            ])
            
            # 如果提供了LLM客户端，使用LLM生成摘要
            if llm_client:
                from app.core.prompts import CONVERSATION_SUMMARY_PROMPT
                
                prompt = CONVERSATION_SUMMARY_PROMPT.format(
                    conversation=conversation_text
                )
                
                messages = [{"role": "user", "content": prompt}]
                response = await llm_client.chat(messages, max_tokens=200)
                
                summary = response.get("content", "")
                logger.info(f"对话摘要生成成功 | 用户: {user_id}")
                
                return summary
            else:
                # 简单摘要：返回前100字符
                return conversation_text[:100] + "..."
                
        except Exception as e:
            logger.error(f"生成对话摘要失败: {e}")
            return None
    
    async def get_context_messages(
        self,
        user_id: str,
        system_prompt: str,
        max_history: int = 5
    ) -> List[Dict[str, str]]:
        """
        获取带系统提示词的上下文消息
        
        Args:
            user_id: 用户ID
            system_prompt: 系统提示词
            max_history: 最大历史轮数
            
        Returns:
            完整的消息列表
        """
        # 系统消息
        messages = [{"role": "system", "content": system_prompt}]
        
        # 获取历史
        history = await self.get_history(user_id, limit=max_history * 2)
        
        # 格式化历史
        history_messages = self.format_history_for_llm(history)
        
        # 合并
        messages.extend(history_messages)
        
        return messages


# 全局记忆管理器实例
conversation_memory = ConversationMemory()


# 便捷函数
async def save_user_message(user_id: str, content: str, metadata: Dict = None) -> bool:
    """保存用户消息"""
    return await conversation_memory.save_message(user_id, "user", content, metadata)


async def save_assistant_message(user_id: str, content: str, metadata: Dict = None) -> bool:
    """保存助手消息"""
    return await conversation_memory.save_message(user_id, "assistant", content, metadata)


async def get_conversation_history(user_id: str, limit: int = None) -> List[Dict]:
    """获取对话历史"""
    return await conversation_memory.get_history(user_id, limit)


async def clear_conversation(user_id: str) -> bool:
    """清除对话历史"""
    return await conversation_memory.clear_history(user_id)

